package com.dzl.util;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;

import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

public class RedisUtil {

    private static RedissonClient redissonClient = SpringContextUtil.getBean(RedissonClient.class);

    public static final String LOCK_PREFIX = "DZL_BUSINESS_REDIS_LOCK:";

    public static final String EXPRESS_QUERY_LOCK_PREFIX = "WELFARE_EXPRESS_LOCK_PREFIX:";

    public static final String ORDER_BLUE_BROTHERS_PREFIX = "ORDER_BLUE_BROTHERS_PREFIX:";

    public static final String ORDER_REFUND_LOCK_PREFIX = "WELFARE_ORDER_REFUND_PREFIX:";

    public static final String ORDER_CANCEL_LOCK_PREFIX = "ORDER_CANCEL_LOCK_PREFIX:";

    public static final String ORDER_RELEASE_LOCK_QUANTITY_PREFIX = "ORDER_RELEASE_LOCK_QUANTITY_PREFIX:";

    public static final String ORDER_ORDER_LOCK_USER_OPT_PREFIX = "ORDER_ORDER_LOCK_USER_OPT_PREFIX:";

    public static final String EXCHANGE_GOODS_OPT = "EXCHANGE_GOODS_OPT:";



  //============================String=============================

    /**
     * 普通缓存获取
     * @param key 键
     * @return 值
     */
    public static Object get(String key) {
        Object obj = null;
        try {
            obj = key == null ? null : redissonClient.getBucket(key).get();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return obj;
    }

    /**
     * 普通缓存放入
     * @param key   键
     * @param value 值
     * @return true成功 false失败
     */
    public static boolean set(String key, Object value) {
        try {
            redissonClient.getBucket(key).set(value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 普通缓存放入并设置时间
     * @param key   键
     * @param value 值
     * @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期
     * @return true成功 false 失败
     */
    public static boolean set(String key, Object value, long time) {
        try {
            if (time > 0) {
                redissonClient.getBucket(key).set(value, time, TimeUnit.SECONDS);
            } else {
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 移除值为value的
     *
     * @param key 键,可以是多个键
     * @return 移除的个数
     */
    public static long delete(String... key) {
        try {
            Long count = redissonClient.getKeys().delete(key);
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 获取锁
     *
     * @param key 锁名称
     * @return
     * @date 2020/9/29 18:41
     * @author lishunxing
     */
    public static RLock lock(String key) {
        RLock lock = redissonClient.getLock(LOCK_PREFIX + MD5Util.getMd5(key));
        return lock;
    }

    /**
     *
     * @Description:异步锁 (不等待，直接返回)
     * @param key  键
     * @param expireTime 强制解锁时间 （单位毫秒）
     * @return
     * @throws InterruptedException
     * boolean
     * @exception:
     * @author: nichangshun
     * @time:2020年8月3日 上午10:04:58
     */
    public static boolean tryLock(String key,int expireTime){
        return tryLock(key,0,expireTime);
    }

    /**
     *
     * @Description:解锁
     * @param key
     * void
     * @exception:
     * @author: nichangshun
     * @time:2020年8月5日 下午2:58:31
     */
    public static void unlock(String key){

        RLock disLock = redissonClient.getLock(LOCK_PREFIX + MD5Util.getMd5(key));

        disLock.unlock();
    }

    /**
     *
     * @Description:异步锁 (等待waitTime 秒后，直接返回)
     * @param key  键
     * @param waitTime 等待时间   （单位毫秒）
     * @param expireTime 强制解锁时间 （单位毫秒）
     * @return
     * @throws InterruptedException
     * boolean
     * @exception:
     * @author: nichangshun
     * @time:2020年8月3日 上午10:03:32
     */
    public static boolean tryLock(String key,int waitTime,int expireTime){
        //获得锁
        RLock disLock = redissonClient.getLock(LOCK_PREFIX + MD5Util.getMd5(key));

        //如果没有获得锁，则等待 waitTime 秒钟 。 expire 秒后，强制解锁
        boolean isLock = false;
        try {
            isLock = disLock.tryLock(waitTime, expireTime, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return isLock;
    }

    /**
     *
     * @Description:阻塞锁 （expireTime 秒后，强制解锁）
     * @param key
     * @param expireTime
     * @throws InterruptedException
     * void
     * @exception:
     * @author: nichangshun
     * @time:2020年8月3日 上午10:08:27
     */
    public static void lock(String key,int expireTime) throws InterruptedException {
        //获得锁
        RLock disLock = redissonClient.getLock(LOCK_PREFIX + MD5Util.getMd5(key));
        //lock提供带timeout参数，timeout结束强制解锁，防止死锁
        disLock.lock(expireTime, TimeUnit.MILLISECONDS);
    }

    /**
     * List缓存放入
     *
     * @param key   键
     * @param value 值
     * @return true成功 false失败
     */
    public static boolean setList(String key, Object value) {
        try {
            redissonClient.getList(key).add(0, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * List缓存获取
     *
     * @param key
     * @param indexList 索引位置
     * @return
     */
    public static List<Object> getList(String key, int[] indexList) {
        try {
            if (indexList == null || indexList.length == 0) {
                return redissonClient.getList(key).readAll();
            }
            return redissonClient.getList(key).get(indexList);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * List缓存清除
     *
     * @param key
     * @return
     */
    public static boolean deleteList(String key) {
        try {
            return redissonClient.getList(key).delete();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * Set缓存放入
     *
     * @param key   键
     * @param value 值
     * @return true成功 false失败
     */
    public static boolean setSet(String key, Object value) {
        try {
            return redissonClient.getSet(key).add(value);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * Set批量保存
     *
     * @param key 键
     * @param all 集合
     * @return
     */
    public static boolean setSetAll(String key, Collection all) {
        try {
            return redissonClient.getSet(key).addAll(all);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * Set缓存获取
     *
     * @param key 键
     * @param num 随机获取的数量
     * @return
     */
    public static Set<Object> getSet(String key, Integer num) {
        try {
            if (num != null) {
                return redissonClient.getSet(key).random(num);
            }
            return redissonClient.getSet(key);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * Set缓存清除
     *
     * @param key
     * @return
     */
    public static boolean deleteSet(String key) {
        try {
            return redissonClient.getSet(key).delete();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}
